#include <tool/TangentSpaceCalculator.h>

namespace ne
{
    Vector3 TangentSpaceCalculator::CalculateTangent(const Vector3 points[3],
                                                     const Vector2 uvs[3])
    {
        Vector3 v1 = points[1] - points[0];
        Vector3 v2 = points[2] - points[0];
        Vector2 c1 = uvs[1] - uvs[0];
        Vector2 c2 = uvs[2] - uvs[0];
        Vector2 c(c2.y, -c1.y);
        Vector3 tangent(c.dotProduct(Vector2(v1.x, v2.x)),
                        c.dotProduct(Vector2(v1.y, v2.y)),
                        c.dotProduct(Vector2(v1.z, v2.z)));
        return tangent.getUnit();
    }

    Vector3 TangentSpaceCalculator::CalculateBinormal(const Vector3 points[3],
                                                      const Vector2 uvs[3])
    {
        Vector3 v1 = points[1] - points[0];
        Vector3 v2 = points[2] - points[0];
        Vector2 c1 = uvs[1] - uvs[0];
        Vector2 c2 = uvs[2] - uvs[0];
        Vector2 c(-c2.x, c1.x);
        Vector3 binormal(c.dotProduct(Vector2(v1.x, v2.x)),
                         c.dotProduct(Vector2(v1.y, v2.y)),
                         c.dotProduct(Vector2(v1.z, v2.z)));
        return binormal.getUnit();
    }

    bool TangentSpaceCalculator::CalculateTangent(const Vector3 points[3],
                                                  const Vector3 normals[3],
                                                  const Vector2 uvs[3],
                                                  Vector3 tangents[3])
    {
        bool res = true;
        Vector3 tangent = CalculateTangent(points, uvs);
        for (uint32_t i=0; i<3; ++i)
        {
            Vector3 binormal = normals[i].crossProduct(tangent);
            tangents[i] = binormal.crossProduct(normals[i]);
            if (tangents[i].normalize() <= 0.0f)
            {
                res = false;
            }
        }
        return res;
    }
}
